package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.domain.ApiResponse;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.dto.TbDeviceAndInfoCreateDTO;
import com.ruoyi.system.domain.enums.PackageTypeEnum;
import com.ruoyi.system.domain.enums.TaskStatusEnum;
import com.ruoyi.system.domain.enums.TaskTypeEnum;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IInteractionService;
import com.ruoyi.system.service.ITbDownloadTokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class InteractionServiceImpl implements IInteractionService {


    @Resource
    private TbDeviceInfoMapper deviceInfoMapper;


    @Resource
    private TbDeviceMapper tbDeviceMapper;


    @Resource
    private TbTaskDetailMapper tbTaskDetailMapper;

    @Resource
    private TbTaskMapper tbTaskMapper;


    @Resource
    private TbTaskTargetMapper taskTargetMapper;


    @Resource
    private TbAppCatalogMapper tbAppCatalogMapper;


    @Resource
    private TbAppVersionMapper tbAppVersionMapper;


    @Resource
    private TbDataPackageMapper dataPackageMapper;


    @Resource
    private TbTaskDetailLogsMapper taskDetailLogsMapper;


    @Resource
    private TbDeviceAppsMapper tbDeviceAppsMapper;


    @Resource
    private TbDeviceAppLogsMapper tbDeviceAppLogsMapper;


    @Resource
    private TbDeviceDataPackagesMapper tbDeviceDataPackagesMapper;


    @Resource
    private TbDeviceDataPackageLogsMapper tbDeviceDataPackageLogsMapper;


    @Resource
    private ITbDownloadTokenService downloadTokenService;

    @Resource
    private TbOfflineTaskDetailLogsMapper offlineTaskDetailLogsMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public R registrationAgent(TbDeviceAndInfoCreateDTO dto) {
        try {
            // 1. 参数基础校验
            if (dto == null) {
                return R.fail("请求参数不能为空");
            }
            // 2. 关键参数非空校验
            if (StringUtils.isBlank(dto.getSn())) {
                return R.fail("设备SN号不能为空");
            }

            // 4. 业务逻辑处理
            TbDevice tbDevice = tbDeviceMapper.selectByDevSn(dto.getSn());
            if (tbDevice != null) {
                // 将设备状态改为已注册,已登记
                tbDevice.setRegistrationStatus(1);
                tbDevice.setId(tbDevice.getId());
                tbDevice.setUpdateTime(new Date());
                tbDevice.setUpdateBy("OTA");
                tbDevice.setDevSn(dto.getSn());
                tbDevice.setDevPartNum(dto.getPartNumber());
                tbDeviceMapper.updateTbDevice(tbDevice);


            } else {
                // 插入设备信息
                TbDevice tbDevicevo = new TbDevice();
                tbDevicevo.setRegistrationStatus(1);
                tbDevicevo.setDevSn(dto.getSn());
                tbDevicevo.setDevPartNum(dto.getPartNumber());
                tbDevicevo.setRecordStatus(0);
                tbDevicevo.setRegistrationTime(new Date());
                tbDevicevo.setCreateTime(new Date());
                tbDevicevo.setCreateBy("OTA");

                int deviceInsertCount = tbDeviceMapper.insertTbDevice(tbDevicevo);
                if (deviceInsertCount <= 0) {
                    return R.fail("设备注册失败");
                }

            }
            //查询到 设备信息
            TbDeviceInfo tbDeviceInfo = new TbDeviceInfo();
            BeanUtils.copyProperties(dto, tbDeviceInfo);
            tbDeviceInfo.setDevSn(dto.getSn());
            tbDeviceInfo.setConnectionStatus(dto.getEthernetState());
            tbDeviceInfo.setCreateTime(new Date());
            tbDeviceInfo.setCreateBy("OTA");

            int infoInsertCount = deviceInfoMapper.insertTbDeviceInfo(tbDeviceInfo);
            if (infoInsertCount > 0) {
                return R.ok("设备注册成功");
            } else {
                return R.fail("设备注册失败");
            }
        } catch (Exception e) {
            // 记录异常日志
            log.error("设备注册处理异常，SN: {}, 错误信息: {}", dto != null ? dto.getSn() : "null", e.getMessage(), e);
            return R.fail("系统处理异常，请联系管理员");
        }

    }


    @Override
    public DeviceTaskResultResponse getDeviceTaskResults(String devSN) {

        try {
            // 查询任务统计信息
            TaskStatistics statistics = tbTaskDetailMapper.selectTaskStatisticsByDevSn(devSN);

            if (statistics == null || statistics.getTotalTasks() == null || statistics.getTotalTasks() == 0) {
                return createEmptyResponse(devSN);
            }
            // 查询任务详情
            List<TaskExecutionResult> taskResults = tbTaskDetailMapper.selectTaskResultsByDevSn(devSN);

            if (taskResults == null || taskResults.isEmpty()) {
                return createEmptyResponse(devSN);
            }
            // 丰富任务结果信息
            List<TaskExecutionResult> enrichedResults = enrichTaskResults(taskResults);
            // 构建响应
            return buildResponse(devSN, statistics, enrichedResults);

        } catch (Exception e) {
            throw new RuntimeException("获取任务执行结果失败: " + e.getMessage());
        }

    }


    @Override
    public ApiResponse<DevicePendingTasksResponse> getDevicePendingTasks(String devSN) {
        try {
            // 查询待执行任务数量
            Integer pendingCount = tbTaskDetailMapper.countPendingTasksByDevSn(devSN);

            if (pendingCount == null || pendingCount == 0) {
                return ApiResponse.success("该设备暂无待执行任务", createEmptyResponse1(devSN));
            }

            // 查询待执行任务详情
            List<PendingTask> pendingTasks = tbTaskDetailMapper.selectPendingTasksByDevSn(devSN);

            if (pendingTasks == null || pendingTasks.isEmpty()) {
                return ApiResponse.success("该设备暂无待执行任务", createEmptyResponse1(devSN));
            }
            // 任务信息
            List<PendingTask> enrichedTasks = enrichPendingTasks(pendingTasks);

            // 构建响应
            DevicePendingTasksResponse response = buildResponse1(devSN, pendingCount, enrichedTasks);

            return ApiResponse.success("获取待执行任务成功", response);

        } catch (Exception e) {
            return ApiResponse.error("获取待执行任务失败: " + e.getMessage());
        }

    }

    @Override
    public ApiResponse<List<TaskMessage>> getDeviceAllPendingTasks(String devSN) {
        // 1. 验证设备是否存在
        try {
            TbDevice device = tbDeviceMapper.selectByDeviceSn(devSN);
            if (device == null) {
                return ApiResponse.error("设备不存在,或者设备不能使用!");
            }
            // 2. 获取设备待执行的任务
            List<TaskMessage> pendingTasks = getPendingTasksForDevice(device.getId());
            if (pendingTasks.size() == 0) {
                return ApiResponse.error("无待执行任务");
            }
            return ApiResponse.success("获取设备所有待执行任务成功", pendingTasks);

        } catch (Exception e) {

            return ApiResponse.error("获取待执行任务失败: " + e.getMessage());
        }

    }


    private List<TaskMessage> getPendingTasksForDevice(Long deviceId) {
        List<TaskMessage> result = new ArrayList<>();

        // 1. 获取设备待执行的任务目标
        List<TbTaskTarget> pendingTaskTargets = taskTargetMapper.selectTargetByDeviceId(deviceId);
        if (pendingTaskTargets.isEmpty()) {
            return result;
        }
        // 2. 按任务分组处理
        Map<Long, List<TbTaskTarget>> taskTargetsByTaskId = groupTaskTargetsByTaskId(pendingTaskTargets);

        for (Map.Entry<Long, List<TbTaskTarget>> entry : taskTargetsByTaskId.entrySet()) {
            Long taskId = entry.getKey();
            List<TbTaskTarget> taskTargets = entry.getValue();

            // 3. 获取任务信息
            TbTask task = tbTaskMapper.selectTbTaskById(taskId);
            if (task == null) {
                continue;
            }

            // 4. 转换任务消息
            TaskMessage taskMessage = convertToTaskMessage(task, taskTargets, deviceId);
            if (taskMessage != null && !taskMessage.getPackages().isEmpty()) {
                result.add(taskMessage);
            }
        }

        return result;
    }


    private Map<Long, List<TbTaskTarget>> groupTaskTargetsByTaskId(List<TbTaskTarget> taskTargets) {
        Map<Long, List<TbTaskTarget>> result = new HashMap<>();

        for (TbTaskTarget target : taskTargets) {
            TbTaskDetail detail = tbTaskDetailMapper.selectTbTaskDetailById(target.getTaskDetailId());
            if (detail != null) {
                result.computeIfAbsent(detail.getTaskId(), k -> new ArrayList<>()).add(target);
            }
        }

        return result;
    }


    private TaskMessage convertToTaskMessage(TbTask task, List<TbTaskTarget> taskTargets, Long deviceId) {
        TaskMessage taskMessage = new TaskMessage();
        taskMessage.setTaskId(task.getId());
        taskMessage.setTaskname(task.getTaskName());

        // 获取包信息
        List<Packages> packages = new ArrayList<>();
        for (TbTaskTarget target : taskTargets) {
            List<Packages> taskPackages = getPackagesForTaskTarget(target, deviceId);
            if (taskPackages != null && !taskPackages.isEmpty()) {
                packages.addAll(taskPackages);
            }
        }

        taskMessage.setPackages(packages);
        return taskMessage;
    }


    private List<Packages> getPackagesForTaskTarget(TbTaskTarget taskTarget, Long deviceId) {
        List<Packages> packages = new ArrayList<>();
        // 获取任务详情
        TbTaskDetail taskDetail = tbTaskDetailMapper.selectTbTaskDetailById(taskTarget.getTaskDetailId());
        if (taskDetail == null) {
            return packages;
        }

        // 根据任务类型处理不同的包
        switch (taskDetail.getTaskType()) {
            case 3: // 应用安装
            case 4: // 应用升级
                Packages appPackage = getAppPackage(taskDetail, deviceId);
                if (appPackage != null) {
                    packages.add(appPackage);
                }
                break;
            case 5: // 应用卸载
                Packages uninstallPackage = getUninstallPackage(taskDetail);
                if (uninstallPackage != null) {
                    packages.add(uninstallPackage);
                }
                break;
            case 1: // 数据推送
            case 2: // 数据更新

                Packages dataPackage = getDataPackage(taskDetail);
                if (dataPackage != null) {
                    packages.add(dataPackage);
                }
                break;
            default:
        }

        return packages;
    }

    private Packages getAppPackage(TbTaskDetail taskDetail, Long deviceId) {
        // 获取新版本应用信息
        TbAppVersion newVersion = tbAppVersionMapper.selectByPackageIdAndCode(taskDetail.getPackageId(), taskDetail.getPackageVersioncode(), taskDetail.getPackageVersionnumber());
        if (newVersion == null) {
            return null;
        }

        Packages pkg = new Packages();
        //通过 appName 获取 PackageName
        String packageName = tbAppVersionMapper.selectByPackageNameByCondition(taskDetail.getPackageVersionnumber(), taskDetail.getPackageVersioncode(), taskDetail.getAppName());
        pkg.setAppname(packageName);
        pkg.setAppversion(newVersion.getPackageVersionnumber());
        pkg.setVersioncode(Integer.valueOf(newVersion.getPackageVersioncode()));

        // 检查设备是否安装过旧版本
        TbAppVersion oldVersion = getLastSuccessAppVersion(deviceId, taskDetail.getAppName());

        if (oldVersion != null) {
            // 设备安装过旧版本，查找差分包
            TbAppVersion diffPackage = findDiffPackage(oldVersion, newVersion);

            if (diffPackage != null) {
                // 找到差分包，返回差分包信息
                setDiffPackageInfo(pkg, oldVersion, newVersion, diffPackage);
                pkg.setPackageType(2); // 差分包
            } else {
                // 没找到差分包，返回全量包
                setFullPackageInfo(pkg, newVersion);
                pkg.setPackageType(1); // 全量包
            }
        } else {
            // 设备没安装过，返回全量包
            setFullPackageInfo(pkg, newVersion);
            pkg.setPackageType(1); // 全量包
        }

        return pkg;
    }


    private TbAppVersion findDiffPackage(TbAppVersion oldVersion, TbAppVersion newVersion) {

        return tbAppVersionMapper.selectDiffPackageByVersions(oldVersion.getPackageName(), oldVersion.getPackageVersioncode(), oldVersion.getPackageVersionnumber(), newVersion.getPackageVersioncode(), newVersion.getPackageVersionnumber());

    }

    private void setFullPackageInfo(Packages pkg, TbAppVersion version) {
        // 生成GUID并存储到Redis

        pkg.setDownloadtoken(version.getPackageUrl());
        pkg.setHash(version.getPackageHash());
        // 全量包不需要设置新旧版本信息
        pkg.setOldfileName(null);
        pkg.setOldHash(null);
        pkg.setNewFileName(null);
        pkg.setNewHash(null);
    }


    private void setDiffPackageInfo(Packages pkg, TbAppVersion oldVersion, TbAppVersion newVersion, TbAppVersion diffPackage) {
        // 设置差分包信息
        pkg.setDownloadtoken(diffPackage.getPackageUrl());
        pkg.setHash(diffPackage.getPackageHash());

        // 设置新旧版本信息
        //文件名 为 Packageurl 字符串
        /**
         *    String[] parts = url.split("/");
         *         // 获取最后一段
         *         String lastSegment = parts[parts.length - 1];
         */
        String[] parts = oldVersion.getPackageUrl().split("/");
        String oldFileName = parts[parts.length - 1];
        pkg.setOldfileName(oldFileName);
        pkg.setOldHash(oldVersion.getPackageHash());

        String[] strings = newVersion.getPackageUrl().split("/");
        String newfileName = strings[strings.length - 1];
        pkg.setNewFileName(newfileName);
        pkg.setNewHash(newVersion.getPackageHash());
    }

    private Packages getUninstallPackage(TbTaskDetail taskDetail) {
        Packages pkg = new Packages();
        pkg.setAppname(taskDetail.getAppName());
        pkg.setPackageType(4); // 卸载
        // 卸载任务不需要版本信息和下载链接
        return pkg;
    }

    private Packages getDataPackage(TbTaskDetail taskDetail) {
        // 获取数据包信息
        TbDataPackage dataPackage = dataPackageMapper.selectTbDataPackageById(taskDetail.getPackageId());
        if (dataPackage == null) {
            return null;
        }

        Packages pkg = new Packages();
        pkg.setAppname(taskDetail.getPackageName());
        pkg.setAppversion(dataPackage.getPackageVersionnumber());
        pkg.setVersioncode(Integer.valueOf(dataPackage.getPackageVersioncode()));
        pkg.setDownloadtoken(dataPackage.getPackageUrl());
        pkg.setHash(dataPackage.getPackageHash());
        pkg.setPackageType(3); // zip数据包

        return pkg;
    }

    private TbAppVersion getLastSuccessAppVersion(Long deviceId, String appName) {
        // 获取设备上次执行成功的相同应用的任务目标
        List<TbTaskTarget> lastSuccessTargets = taskTargetMapper.selectLastSuccessTaskTargetByApp(deviceId, appName);

        if (lastSuccessTargets.isEmpty()) {
            return null;
        }
        // 取最近的一个成功记录
        TbTaskTarget lastTarget = lastSuccessTargets.get(0);
        TbTaskDetail taskDetail = tbTaskDetailMapper.selectTbTaskDetailById(lastTarget.getTaskDetailId());

        if (taskDetail != null && taskDetail.getPackageId() != null) {
            return tbAppVersionMapper.selectByPackageId(taskDetail.getPackageId());
        }
        return null;

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean  postDeviceTaskResults(TaskStatusPost post) {
        try {
            // 验证参数
            TbDevice device = tbDeviceMapper.selectByDeviceSn(post.getDeviceSN());
            if (device == null) {
                return false;
            }
            //查询有没有对应的应用 或者数据包,否则上报失败
            TbAppVersion appVersion = tbAppVersionMapper.selectByAppNameAndCodeAndNum(post.getBundleName()
                    , post.getAppVersion(), post.getVersionCode());
            if (appVersion == null) {
                //尝试获取数据包
                TbDataPackage dataPackage = dataPackageMapper.selectByAppNameAndCodeAndNum(post.getBundleName()
                        , post.getAppVersion(), post.getVersionCode());
                if (dataPackage == null) {
                    return false;
                }
            }

            if (post.getTaskId() == null) {
                return false;
            }
            if (post.getTaskId() == 0L) {
                // 做离线任务上报,直接记录日志
                TbOfflineTaskDetailLogs offlineTaskDetailLogs = new TbOfflineTaskDetailLogs();
                offlineTaskDetailLogs.setTaskId(post.getTaskId());
                offlineTaskDetailLogs.setTaskDetailId(0L);
                offlineTaskDetailLogs.setDeviceSn(post.getDeviceSN());
                offlineTaskDetailLogs.setPackageName(post.getBundleName());
                offlineTaskDetailLogs.setPackageVersionnumber(post.getAppVersion());
                offlineTaskDetailLogs.setPackageVersioncode(post.getVersionCode());
                offlineTaskDetailLogs.setOperationType(1);
                if (!post.isSuccess() && post.getRemark() != null) {
                    offlineTaskDetailLogs.setStatus(0);
                    offlineTaskDetailLogs.setErrorMessage(post.getRemark());
                }else if (post.isSuccess()) {
                    offlineTaskDetailLogs.setStatus(1);
                    //更新应用下载次数
                    updateDownloadCount(post.getBundleName(), post.getAppVersion(), post.getVersionCode());
                }
                offlineTaskDetailLogs.setCreateBy("OTA");
                offlineTaskDetailLogs.setCreateTime(new Date());
                offlineTaskDetailLogsMapper.insertTbOfflineTaskDetailLogs(offlineTaskDetailLogs);
                saveToDeviceOfflineInstallTables(post, device);
            } else {
                //在线任务上报
                // 2. 查找对应的任务明细
                TbTaskDetail taskDetail = findTaskDetail(post);
                if (taskDetail == null) {
                    return false;
                }
                // 3. 查找对应的任务目标记录
                TbTaskTarget taskTarget = taskTargetMapper.selectByDetailIdAndDeviceId(taskDetail.getId(), device.getId());
                if (taskTarget == null) {
                    return false;
                }
                // 4. 更新任务目标表状态
                updateTaskTargetStatus(taskTarget, post);
                // 5. 更新任务明细表的统计信息
                updateTaskDetailStatistics(taskDetail, post);
                // 6. 记录执行日志
                saveExecutionLog(post, device, taskDetail, taskTarget);
                // 7. 检查并更新主任务状态
                checkAndUpdateMainTaskStatus(post.getTaskId());
                if (post.isSuccess()) {
                    saveToDeviceInstallTables(post, device, taskDetail); // ← 调用位置
                    //更新应用下载次数
                    updateDownloadCount(post.getBundleName(), post.getAppVersion(), post.getVersionCode());
                }
            }

        } catch (Exception e) {
            throw new RuntimeException("上报任务执行结果失败", e);
        }
        return true;
    }

    private void updateDownloadCount(String bundleName, String appVersionnumber, String versionCode) {
        TbAppVersion appVersion = tbAppVersionMapper.selectBypackageNameAndVersion(bundleName, appVersionnumber, versionCode);
        if (appVersion != null) {
            appVersion.setDownloadCount(appVersion.getDownloadCount() + 1);
            tbAppVersionMapper.updateTbAppVersion(appVersion);
        }
        //如果为空, 则尝试获取数据包
        TbDataPackage dataPackage = dataPackageMapper.selectByAppNameAndCodeAndNum(bundleName, appVersionnumber, versionCode);
        if (dataPackage != null) {
            dataPackage.setDownloadCount(dataPackage.getDownloadCount() + 1);
            dataPackageMapper.updateTbDataPackage(dataPackage);
        }
    }

    private void saveToDeviceOfflineInstallTables(TaskStatusPost post, TbDevice device) {
        try {
            // 根据文件扩展名判断是应用还是数据包
            if (post.getDownloadtoken().endsWith(".hap")) {
                // 安装的是应用
                TbAppVersion appVersion = tbAppVersionMapper.selectBypackageNameAndVersion(
                        post.getBundleName(), post.getAppVersion(), post.getVersionCode());

                if (appVersion != null) {
                    // 1. 先禁用同名的旧应用
                    disableOldApps(post.getDeviceSN(), post.getBundleName());

                    // 2. 插入新的应用记录
                    TbDeviceApps newApp = createOfflineDeviceAppRecord(post, device, appVersion);
                    tbDeviceAppsMapper.insertTbDeviceApps(newApp);

                    // 3. 记录应用更新日志
                    TbDeviceAppLogs appLog = createOfflineDeviceAppLog(post, device, appVersion, newApp.getId());
                    tbDeviceAppLogsMapper.insertTbDeviceAppLogs(appLog);
                }
            } else if (post.getDownloadtoken().endsWith(".zip")) {
                // zip数据包
                TbDataPackage dataPackage = dataPackageMapper.selectByPackageNameAndVersion(
                        post.getBundleName(), post.getAppVersion(), post.getVersionCode());

                if (dataPackage != null) {
                    // 1. 先禁用同名的旧数据包
                    disableOldDataPackages(post.getDeviceSN(), post.getBundleName());

                    // 2. 插入新的数据包记录
                    TbDeviceDataPackages newPackage = createOfflineDeviceDataPackageRecord(post, device, dataPackage);
                    tbDeviceDataPackagesMapper.insertTbDeviceDataPackages(newPackage);

                    // 3. 记录数据包更新日志
                    TbDeviceDataPackageLogs packageLog = createOfflineDeviceDataPackageLog(post, device, dataPackage, newPackage.getId());
                    tbDeviceDataPackageLogsMapper.insertTbDeviceDataPackageLogs(packageLog);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("上报任务执行结果失败", e);
        }
    }

    /**
     * 创建设备离线应用记录
     */
    private TbDeviceApps createOfflineDeviceAppRecord(TaskStatusPost post, TbDevice device, TbAppVersion appVersion) {
        TbDeviceApps app = new TbDeviceApps();
        app.setDeviceSn(post.getDeviceSN());
        app.setPackageName(post.getBundleName());
        app.setPackageVersioncode(post.getVersionCode());
        app.setPackageVersionnumber(post.getAppVersion());
        //通过包名获取应用名称
        String appName = tbAppVersionMapper.selectBYPackageName(appVersion.getPackageName());
        if (appName != null) {
            app.setAppName(appName); // 从应用版本表获取应用名称
        }
        app.setInstallDate(new Date());
        app.setLastUpdateDate(new Date());
        app.setIsSystemApp(0);
        app.setStatus(1); // 启用状态
        app.setCreateBy("OTA_OFFLINE");
        app.setCreateTime(new Date());
        return app;
    }

    /**
     * 创建设备离线数据包记录
     */
    private TbDeviceDataPackages createOfflineDeviceDataPackageRecord(TaskStatusPost post, TbDevice device, TbDataPackage dataPackage) {
        TbDeviceDataPackages deviceDataPackage = new TbDeviceDataPackages();
        deviceDataPackage.setDeviceSn(post.getDeviceSN());
        deviceDataPackage.setPackageId(dataPackage.getId());
        deviceDataPackage.setPackageName(post.getBundleName());
        deviceDataPackage.setPackageVersioncode(post.getVersionCode());
        deviceDataPackage.setPackageVersionnumber(post.getAppVersion());
        deviceDataPackage.setPackageType(dataPackage.getPackageType());
        deviceDataPackage.setPackageSize(BigDecimal.valueOf(dataPackage.getPackageSize()));
        deviceDataPackage.setPackageHash(dataPackage.getPackageHash());
        deviceDataPackage.setInstallDate(new Date());
        deviceDataPackage.setLastUpdateDate(new Date());
        deviceDataPackage.setIsSystemPackage(1);
        deviceDataPackage.setStatus(1); // 启用状态
        deviceDataPackage.setIsForceUpdate(dataPackage.getIsForceUpdate() != null ? dataPackage.getIsForceUpdate() : 0);
        deviceDataPackage.setCreateBy("OTA_OFFLINE");
        deviceDataPackage.setCreateTime(new Date());
        return deviceDataPackage;
    }

    /**
     * 创建离线应用更新日志
     */
    private TbDeviceAppLogs createOfflineDeviceAppLog(TaskStatusPost post, TbDevice device, TbAppVersion appVersion, Long appId) {
        TbDeviceAppLogs log = new TbDeviceAppLogs();
        log.setDeviceSn(post.getDeviceSN());
        log.setAppId(appId);
        log.setPackageName(post.getBundleName());
        log.setPackageVersioncode(post.getVersionCode());
        log.setPackageVersionnumber(post.getAppVersion());
        log.setPackageContent("设备"+device.getDevSn() +"安装更新了"+appVersion.getPackageName()+"的"+appVersion.getPackageVersionnumber()+"版本应用"); // 从应用版本表获取更新内容
        log.setPackageStatus(post.isSuccess() ? 1 : 2); // 根据上报结果设置状态
        log.setInstallDate(new Date());
        log.setInstallMethod(2); // 离线安装方式
        log.setCreateBy("OTA_OFFLINE");
        log.setCreateTime(new Date());
        if (!post.isSuccess() && post.getRemark() != null) {
            log.setErrorMessage(post.getRemark());
        }
        return log;
    }

    /**
     * 创建离线数据包更新日志
     */
    private TbDeviceDataPackageLogs createOfflineDeviceDataPackageLog(TaskStatusPost post, TbDevice device, TbDataPackage dataPackage, Long packageId) {
        TbDeviceDataPackageLogs log = new TbDeviceDataPackageLogs();
        log.setDeviceSn(post.getDeviceSN());
        log.setPackageId(packageId);
        log.setPackageName(post.getBundleName());
        log.setPackageVersioncode(post.getVersionCode());
        log.setPackageVersionnumber(post.getAppVersion());
        log.setPackageType(dataPackage.getPackageType());
        log.setUpdateContent("设备"+device.getDevSn() +"安装更新了"+dataPackage.getPackageName()+"的"+dataPackage.getPackageVersionnumber()+"版本数据包");
        log.setUpdateStatus(post.isSuccess() ? 1 : 2); // 根据上报结果设置状态
        log.setUpdateDate(new Date());
        log.setUpdateMethod(2); // 离线更新方式
        log.setCreateBy("OTA_OFFLINE");
        log.setCreateTime(new Date());

        if (!post.isSuccess() && post.getRemark() != null) {
            log.setErrorMessage(post.getRemark());
        }

        return log;
    }


    /**
     * 保存成功任务到设备安装表和更新日志表
     */
    private void saveToDeviceInstallTables(TaskStatusPost post, TbDevice device, TbTaskDetail taskDetail) {
        // 根据任务类型判断是应用还是数据包
        if (isAppTask(taskDetail.getTaskType())) {
            saveToDeviceApps(post, device, taskDetail);
        } else {
            saveToDeviceDataPackages(post, device, taskDetail);
        }
    }

    /**
     * 判断是否为应用任务
     */
    private boolean isAppTask(Integer taskType) {
        // 3=应用安装, 4=应用升级, 5=应用卸载
        return taskType == 3 || taskType == 4 || taskType == 5;
    }

    /**
     * 保存到设备应用表和应用日志表
     */
    private void saveToDeviceApps(TaskStatusPost post, TbDevice device, TbTaskDetail taskDetail) {
        // 1. 先禁用同名的旧应用
        disableOldApps(post.getDeviceSN(), post.getBundleName());
        // 2. 插入新的应用记录
        TbDeviceApps newApp = createDeviceAppRecord(post, device, taskDetail);
        tbDeviceAppsMapper.insertTbDeviceApps(newApp);
        // 3. 记录应用更新日志
        TbDeviceAppLogs appLog = createDeviceAppLog(post, device, taskDetail, newApp.getId());
        tbDeviceAppLogsMapper.insertTbDeviceAppLogs(appLog);
    }

    /**
     * 保存到设备数据包表和数据包日志表
     */
    private void saveToDeviceDataPackages(TaskStatusPost post, TbDevice device, TbTaskDetail taskDetail) {
        // 1. 先禁用同名的旧数据包
        disableOldDataPackages(post.getDeviceSN(), post.getBundleName());

        // 2. 插入新的数据包记录
        TbDeviceDataPackages newPackage = createDeviceDataPackageRecord(post, device, taskDetail);
        tbDeviceDataPackagesMapper.insertTbDeviceDataPackages(newPackage);

        // 3. 记录数据包更新日志
        TbDeviceDataPackageLogs packageLog = createDeviceDataPackageLog(post, device, taskDetail, newPackage.getId());
        tbDeviceDataPackageLogsMapper.insertTbDeviceDataPackageLogs(packageLog);
    }

    /**
     * 禁用同名的旧应用
     */
    private void disableOldApps(String deviceSn, String packageName) {
        TbDeviceApps updateOld = new TbDeviceApps();
        updateOld.setDeviceSn(deviceSn);
        updateOld.setPackageName(packageName);
        updateOld.setUpdateTime(new Date());

        tbDeviceAppsMapper.updateTbDeviceAppsBy(updateOld);
    }

    /**
     * 禁用同名的旧数据包
     */
    private void disableOldDataPackages(String deviceSn, String packageName) {
        TbDeviceDataPackages updateOld = new TbDeviceDataPackages();
        updateOld.setDeviceSn(deviceSn);
        updateOld.setPackageName(packageName);
        updateOld.setUpdateTime(new Date());
        tbDeviceDataPackagesMapper.updateTbDeviceDataPackagesBy(updateOld);
    }

    /**
     * 创建设备应用记录
     */
    private TbDeviceApps createDeviceAppRecord(TaskStatusPost post, TbDevice device, TbTaskDetail taskDetail) {
        TbDeviceApps app = new TbDeviceApps();
        app.setDeviceSn(post.getDeviceSN());
        app.setPackageName(post.getBundleName());
        app.setPackageVersioncode(post.getVersionCode());
        app.setPackageVersionnumber(post.getAppVersion());
        app.setAppName(taskDetail.getAppName());
        app.setInstallDate(new Date());
        app.setLastUpdateDate(new Date());
        app.setIsSystemApp(0); // 默认非系统应用
        app.setStatus(1); // 启用状态
        app.setCreateBy("OTA");
        app.setCreateTime(new Date());

        return app;
    }

    /**
     * 创建设备数据包记录
     */
    private TbDeviceDataPackages createDeviceDataPackageRecord(TaskStatusPost post, TbDevice device, TbTaskDetail taskDetail) {
        TbDeviceDataPackages dataPackage = new TbDeviceDataPackages();
        dataPackage.setDeviceSn(post.getDeviceSN());
        Long id = dataPackageMapper.selectIdByPackageName(post.getBundleName());
        if (id != null) {
            dataPackage.setPackageId(id);
        }
        dataPackage.setPackageName(post.getBundleName());
        dataPackage.setPackageVersioncode(post.getVersionCode());
        dataPackage.setPackageVersionnumber(post.getAppVersion());

        dataPackage.setPackageType(determinePackageType(post.getBundleName()));
        dataPackage.setPackageSize(BigDecimal.valueOf(taskDetail.getPackageSize()));
        dataPackage.setPackageHash(generatePackageHash(post.getBundleName()));
        dataPackage.setInstallDate(new Date());
        dataPackage.setLastUpdateDate(new Date());
        dataPackage.setIsSystemPackage(1); // 默认系统数据包
        dataPackage.setStatus(1); // 启用状态
        dataPackage.setIsForceUpdate(0); // 默认非强制更新
        dataPackage.setCreateBy("OTA");
        dataPackage.setCreateTime(new Date());

        return dataPackage;
    }

    private String generatePackageHash(String bundeleName) {

        return tbDeviceDataPackagesMapper.selectHashByPackageName(bundeleName);
    }

    private Integer determinePackageType(String bundeleName) {

        return tbDeviceDataPackagesMapper.selectTypeByPackageName(bundeleName);
    }

    /**
     * 创建应用更新日志
     */
    private TbDeviceAppLogs createDeviceAppLog(TaskStatusPost post, TbDevice device, TbTaskDetail taskDetail, Long appId) {
        TbDeviceAppLogs log = new TbDeviceAppLogs();
        log.setDeviceSn(post.getDeviceSN());
        log.setAppId(appId);
        log.setPackageName(post.getBundleName());
        log.setPackageVersioncode(post.getVersionCode());
        log.setPackageVersionnumber(post.getAppVersion());
        log.setPackageContent(taskDetail.getRemark()); // 从任务获取更新内容
        log.setPackageStatus(1); // 成功
        log.setInstallDate(new Date());
        log.setInstallMethod(1); // OTA方式
        log.setCreateBy("OTA");
        log.setCreateTime(new Date());
        return log;
    }

    /**
     * 创建数据包更新日志
     */
    private TbDeviceDataPackageLogs createDeviceDataPackageLog(TaskStatusPost post, TbDevice device, TbTaskDetail taskDetail, Long packageId) {
        TbDeviceDataPackageLogs log = new TbDeviceDataPackageLogs();
        log.setDeviceSn(post.getDeviceSN());
        log.setPackageId(packageId);
        log.setPackageName(post.getBundleName());
        log.setPackageVersioncode(post.getVersionCode());
        log.setPackageVersionnumber(post.getAppVersion());
        log.setPackageType(determinePackageType(post.getBundleName()));
        log.setUpdateContent(taskDetail.getRemark());
        log.setUpdateStatus(1); // 成功
        log.setUpdateDate(new Date());
        log.setUpdateMethod(1); // OTA方式
        log.setCreateBy("OTA");
        log.setCreateTime(new Date());

        return log;
    }


    /**
     * 查找对应的任务明细
     */
    private TbTaskDetail findTaskDetail(TaskStatusPost post) {
        // 先尝试按应用查找
        TbTaskDetail taskDetail = tbTaskDetailMapper.selectByTaskIdAndAppInfo(post.getTaskId(), post.getBundleName()
                , post.getAppVersion(), post.getVersionCode());

        if (taskDetail == null) {
            // 如果应用查找不到，尝试按数据包查找
            taskDetail = tbTaskDetailMapper.selectByTaskIdAndPackageInfo(post.getTaskId(),
                    post.getBundleName(), post.getAppVersion(), post.getVersionCode());
        }
        return taskDetail;
    }


    /**
     * 更新任务目标设备状态
     */
    private void updateTaskTargetStatus(TbTaskTarget taskTarget, TaskStatusPost post) {
        TbTaskTarget updateTarget = new TbTaskTarget();
        updateTarget.setId(taskTarget.getId());
        updateTarget.setTaskDetailId(taskTarget.getTaskDetailId());

        // 设置状态
        int status = post.isSuccess() ? 2 : 3; // 2=成功, 3=失败
        updateTarget.setStatus(status);
        updateTarget.setEndTime(new Date());
        updateTarget.setProgress(post.isSuccess() ? 100.0 : 0.0);

        if (!post.isSuccess() && StringUtils.isNotBlank(post.getRemark())) {
            updateTarget.setErrorMessage(post.getRemark());
        }

        // 如果是失败且需要重试，可以在这里处理重试逻辑, 暂时不考虑
//        if (!post.isSuccess()) {
//            updateTarget.setRetryCount(taskTarget.getRetryCount() + 1);
//        }

        taskTargetMapper.updateTbTaskTarget(updateTarget);
    }


    /**
     * 更新任务明细统计信息
     */
    private void updateTaskDetailStatistics(TbTaskDetail taskDetail, TaskStatusPost post) {
        TbTaskDetail updateDetail = new TbTaskDetail();
        updateDetail.setId(taskDetail.getId());

        // 更新成功/失败计数
        if (post.isSuccess()) {
            updateDetail.setSuccessCount(taskDetail.getSuccessCount() + 1);
        } else {
            updateDetail.setFailCount(taskDetail.getFailCount() + 1);
        }
        // 计算进度
        int totalDevices = taskDetail.getDeviceCount();
        int successDevices = updateDetail.getSuccessCount() == null ? 0 : updateDetail.getSuccessCount();
        int failedDevices = updateDetail.getFailCount() == null ? 0 : updateDetail.getFailCount();
        int completedDevices = successDevices + failedDevices;

        double progress = 0;
        if (totalDevices > 0 && completedDevices >= 0) {
            progress = (completedDevices * 100.0) / totalDevices;
            // 确保进度不超过 100%
            progress = Math.min(progress, 100.0);
        }
        updateDetail.setProgress(progress);

        // 更新状态
        if (completedDevices >= totalDevices) {//执行结束了
            if (successDevices == totalDevices) {
                updateDetail.setStatus(2); // 全部成功
            } else if (failedDevices == totalDevices) {
                updateDetail.setStatus(3); // 全部失败
            } else {
                updateDetail.setStatus(5); // 部分成功
            }
            updateDetail.setEndTime(new Date());
        } else {
            updateDetail.setStatus(1); // 执行中
        }

        tbTaskDetailMapper.updateTbTaskDetail(updateDetail);
    }


    /**
     * 保存执行日志
     */
    private void saveExecutionLog(TaskStatusPost post, TbDevice device, TbTaskDetail taskDetail, TbTaskTarget taskTarget) {
        TbTaskDetailLogs log = new TbTaskDetailLogs();
        log.setTaskId(post.getTaskId());
        log.setTaskDetailId(taskDetail.getId());
        log.setDeviceSn(post.getDeviceSN());
        log.setAirplaneCode(device.getAirplaneCode()); // 假设设备表有飞机编号字段

        // 设置包类型和应用/包名
        log.setPushPackageType(taskDetail.getPushPackageType());
        if (taskDetail.getPushPackageType() == 1) {
            // app
            String appName = tbAppCatalogMapper.selectAppNameByPackageName(post.getBundleName());
            log.setAppName(appName);
        } else { // data_package
            log.setPackageName(post.getBundleName());
        }

        log.setPackageVersionnumber(post.getAppVersion());
        //记录任务开始时间
        log.setStartTime(taskTarget.getStartTime());
        log.setEndTime(taskTarget.getEndTime());
        log.setStatus(post.isSuccess() ? 1 : 2); // 1=成功, 2=失败

        if (!post.isSuccess()) {
            log.setErrorMessage(post.getRemark());
        }
        // 根据任务类型设置操作类型
        log.setOperationType(determineOperationType(taskDetail.getTaskType()));

        taskDetailLogsMapper.insertTbTaskDetailLogs(log);
    }

    /**
     * 根据任务类型确定操作类型
     */
    private Integer determineOperationType(Integer taskType) {
        switch (taskType) {
            case 3:
                return 1; // 应用安装 -> 安装
            case 4:
                return 2; // 应用升级 -> 更新
            case 5:
                return 3; // 应用卸载 -> 卸载
            case 1:
            case 2:
            case 6:
            case 7:
                return 2; // 数据推送/更新/配置推送/更新 -> 更新
            default:
                return 2; // 默认更新
        }
    }

    /**
     * 检查并更新主任务状态
     */
    private void checkAndUpdateMainTaskStatus(Long taskId) {
        // 查询所有任务明细的完成情况
        List<TbTaskDetail> details = tbTaskDetailMapper.selectByTaskId(taskId);

        boolean allCompleted = true;
        boolean hasFailure = false;
        double totalProgress = 0;

        for (TbTaskDetail detail : details) {
            if (detail.getStatus() == 0 || detail.getStatus() == 1) {
                allCompleted = false;
            }
            if (detail.getStatus() == 3 || detail.getStatus() == 5) {
                hasFailure = true;
            }
            totalProgress += detail.getProgress();
        }

        // 计算平均进度
        double avgProgress = details.isEmpty() ? 0 : totalProgress / details.size();

        TbTask updateTask = new TbTask();
        updateTask.setId(taskId);
        updateTask.setTaskProgress(avgProgress);

        if (allCompleted) {
            updateTask.setTaskStatus(hasFailure ? 5 : 4); // 5=失败, 4=完成
            updateTask.setTaskStopTime(new Date());
        } else {
            updateTask.setTaskStatus(2); // 执行中
        }

        tbTaskMapper.updateTbTask(updateTask);


    }


    private List<PendingTask> enrichPendingTasks(List<PendingTask> tasks) {
        return tasks.stream().map(this::enrichSingleTask).collect(Collectors.toList());
    }


    private PendingTask enrichSingleTask(PendingTask task) {
        // 设置任务类型名称
        if (task.getTaskType() != null) {
            task.setTaskTypeName(TaskTypeEnum.getNameByCode(task.getTaskType()));
        }

        // 设置包类型
        if (task.getPackageType() == null && task.getTaskType() != null) {
            if (task.getTaskType() >= 3 && task.getTaskType() <= 5) {
                task.setPackageType("APP");
            } else if (task.getTaskType() == 1 || task.getTaskType() == 2) {
                task.setPackageType("DATA");
            } else {
                task.setPackageType("OTHER");
            }
        }

        // 设置默认值
        if (task.getForceQuitApp() == null) task.setForceQuitApp(false);
        if (task.getAutoRetry() == null) task.setAutoRetry(false);
        if (task.getOverwriteExist() == null) task.setOverwriteExist(false);
        if (task.getPackageSize() == null) task.setPackageSize(0.0);

        return task;
    }


    private DevicePendingTasksResponse createEmptyResponse1(String devSN) {
        DevicePendingTasksResponse response = new DevicePendingTasksResponse();
        response.setDevSN(devSN);
        response.setTotalPendingTasks(0);
        response.setPendingTasks(new ArrayList<>());
        return response;
    }

    private DevicePendingTasksResponse buildResponse1(String devSN, Integer pendingCount, List<PendingTask> pendingTasks) {
        PendingTaskVO pendingTaskVO = new PendingTaskVO();
        List<PendingTaskVO> taskVos = new ArrayList<>();
        for (PendingTask task : pendingTasks) {
            BeanUtils.copyProperties(task, pendingTaskVO);
            if (task.getAppName() != null) {
                pendingTaskVO.setAppOrPackageName(task.getAppName());
            } else if (task.getPackageName() != null) {
                pendingTaskVO.setAppOrPackageName(task.getPackageName());
            }
            taskVos.add(pendingTaskVO);
        }

        DevicePendingTasksResponse response = new DevicePendingTasksResponse();
        response.setDevSN(devSN);
        response.setTotalPendingTasks(pendingCount);
        response.setPendingTasks(taskVos);
        return response;
    }


    private List<TaskExecutionResult> enrichTaskResults(List<TaskExecutionResult> results) {
        return results.stream().map(this::enrichTaskResult).collect(Collectors.toList());
    }

    private TaskExecutionResult enrichTaskResult(TaskExecutionResult result) {
        // 设置枚举值对应的名称
        if (result.getTaskType() != null) {
            result.setTaskTypeName(TaskTypeEnum.getNameByCode(result.getTaskType()));
        }
        if (result.getStatus() != null) {
            result.setStatusDesc(TaskStatusEnum.getDescByCode(result.getStatus()));
        }

        // 设置包类型名称
        if (result.getPackageType() != null) {
            result.setPackageTypeName(PackageTypeEnum.getNameByCode(result.getPackageType()));
        }

        // 处理默认值
        if (result.getProgress() == null) result.setProgress(0.0);
        if (result.getRetryCount() == null) result.setRetryCount(0);
        if (result.getPackageSize() == null) result.setPackageSize(0.0);

        return result;
    }

    private DeviceTaskResultResponse buildResponse(String devSN, TaskStatistics statistics, List<TaskExecutionResult> taskResults) {
        DeviceTaskResultResponse response = new DeviceTaskResultResponse();
        List<TaskExecutionResultVO> resultVos = new ArrayList<>();
        for (TaskExecutionResult taskResult : taskResults) {
            TaskExecutionResultVO vo = new TaskExecutionResultVO();
            BeanUtils.copyProperties(taskResult, vo);
            if (taskResult.getAppName() != null) {
                vo.setAppOrPackgeName(taskResult.getAppName());
            } else if (taskResult.getPackageName() != null) {
                vo.setAppOrPackgeName(taskResult.getPackageName());
            }
            resultVos.add(vo);
        }
        response.setDevSN(devSN);
        response.setTotalTasks(statistics.getTotalTasks());
        response.setSuccessCount(statistics.getSuccessCount() != null ? statistics.getSuccessCount() : 0);
        response.setFailedCount(statistics.getFailedCount() != null ? statistics.getFailedCount() : 0);
        response.setExecutingCount(statistics.getExecutingCount() != null ? statistics.getExecutingCount() : 0);
        response.setPendingCount(statistics.getPendingCount() != null ? statistics.getPendingCount() : 0);
        response.setCancelledCount(statistics.getCancelledCount() != null ? statistics.getCancelledCount() : 0);
        response.setTaskResults(resultVos);
        return response;
    }

    private DeviceTaskResultResponse createEmptyResponse(String devSN) {
        DeviceTaskResultResponse response = new DeviceTaskResultResponse();
        response.setDevSN(devSN);
        response.setTotalTasks(0);
        response.setSuccessCount(0);
        response.setFailedCount(0);
        response.setExecutingCount(0);
        response.setPendingCount(0);
        response.setCancelledCount(0);
        return response;
    }


}
